﻿/*
 * ©2009-2010 XELF
 * http://xelf.info
 */

using System;

namespace XELF.Framework {
	public partial class MathHelper {
		/// <summary>
		/// 二項係数(Binomial Coefficient)
		/// </summary>
		/// <param name="n"></param>
		/// <param name="k"></param>
		/// <returns></returns>
		/// <remarks>
		/// 大きな数では不正確になるか、正しい結果が得られません。その場合には、代わりにBigFraction.Chooseを使ってください。
		/// </remarks>
		public static ulong Choose(uint n, uint k) {
			if (n == 0 && k > 0) return 0;
			if (k == 0 || k == n) return 1;
			if (k < 0 || k > n) throw new ArgumentOutOfRangeException("k");
			if (k * 2 > n) {
				k = n - k;
			}
			double n_k = n - k;
			double a = 1;
			for (uint i = 1; i <= k; i++) {
				a *= (n_k + i) / i;
			}
			return (ulong)(a + 0.5);
		}
	}
}
